package org.csu.corp.service;


import org.csu.corp.entity.*;
import org.csu.corp.persistence.EmployeeMapper;
import org.csu.corp.persistence.SalaryMapper;
import org.csu.corp.persistence.SignMapper;
import org.csu.corp.util.RedisUtil;
import org.csu.corp.util.SalaryUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static org.csu.corp.util.SalaryUtil.splitList;

@Service
public class SalaryService {
    @Autowired
    SalaryMapper salaryMapper;
    @Autowired
    SignMapper signMapper;
    @Autowired
    EmployeeMapper employeeMapper;

    @Resource
    private RedisUtil redisUtil;

    public List<Salary> getAllSalaries() {
        return salaryMapper.getAllSalaries();
    }

    public Integer addSalary(Salary salary) {
        salary.setCreateDate(new Date());
        return salaryMapper.insertSelective(salary);
    }

    public Integer deleteSalaryById(Integer id) {
        return salaryMapper.deleteByPrimaryKey(id);
    }

    public Integer updateSalaryById(Salary salary) {
        return salaryMapper.updateByPrimaryKeySelective(salary);
    }

    /**
     *
     * @param page
     * @param size
     * @param start
     * @param end
     * @param workId
     * @return
     */
    public RespPageBean getEmployeeByPageWithMonthSalary( Integer page,  Integer size, String start, String end, String workId) {
        List<MonthSalary> monthSalaryList = null;
        try {
            monthSalaryList = getMonthSalary(start, end, workId);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        RespPageBean bean = new RespPageBean();
//        bean.setData(monthSalaryList.subList(page * size, (page + 1) * size));
        bean.setData(splitList(monthSalaryList, page, size));
        bean.setTotal((long) monthSalaryList.size());
        return bean;
    }

    /**
     * 根据工号、开始时间、结束时间查找
     * @param start 可为null 或 空字符串
     * @param end
     * @param workId
     * @return
     * @throws ParseException
     */
    private List<MonthSalary> getMonthSalary(String start, String end, String workId) throws ParseException{
//        System.out.println("query");
        String workTime = "08:30:00";
        String byeTime = "17:30:00";
        String key = null;
        if (start == null || start.equals("")) {
            start = null;
            end = null;
            key = "0000-00-00-0000-00-00-" + workId;
        } else {
            start = start + "-01 00:00:00";
            end = end + "-31 23:59:59";
            key = start + "-" + end + "-" + workId;
        }

        List<MonthSalary> monthSalaryList = (List<MonthSalary>) redisUtil.get(key);
        if (monthSalaryList != null) return monthSalaryList;

        List<Sign> signList = signMapper.getEmployeeByPageWithWorkIdAndTime(start, end, workId);
        Map<String, MonthSalary> employeeMapWithWorkId = new HashMap<>(); // 因为是按月计算 所以工号唯一
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");

        for (Sign sign : signList) {
            MonthSalary monthSalary = employeeMapWithWorkId.get(sign.getWorkId());
            if (monthSalary == null) {
                monthSalary = new MonthSalary();
                monthSalary.setEmployee(employeeMapper.getEmployeeByWorkId(sign.getWorkId()));
                monthSalary.setTime(format.parse(format.format(sign.getClockInTime())));
                monthSalary.setTot(SalaryUtil.calSal(monthSalary.getEmployee().getSalary()));
                monthSalary.setLateInSign(0);
                monthSalary.setNormalSign(0);
                monthSalary.setEarlyOutSign(0);
                monthSalary.setSignTime(0);
                monthSalary.setMiss(0);
            }

            String inTime = timeFormat.format(sign.getClockInTime());
            String outTime = timeFormat.format(sign.getClockOutTime());

            boolean normal = true;
            monthSalary.setSignTime(monthSalary.getSignTime() + 1);
            if (workTime.compareTo(inTime) == -1) {
                monthSalary.setLateInSign(monthSalary.getLateInSign() + 1);
                normal = false;
            }
            if (byeTime.compareTo(outTime) == 1) {
                monthSalary.setEarlyOutSign(monthSalary.getEarlyOutSign() + 1);
                normal = false;
            }
            if (normal) monthSalary.setNormalSign(monthSalary.getNormalSign() + 1);

            employeeMapWithWorkId.put(sign.getWorkId(), monthSalary);
        }

        monthSalaryList = new ArrayList<>();
        for(Map.Entry<String, MonthSalary> entry : employeeMapWithWorkId.entrySet()) {
            MonthSalary value = entry.getValue();
            value.setMiss(SalaryUtil.getDaysOfMonth(Integer.valueOf(format.format(value.getTime()).substring(0, 4)), Integer.valueOf(format.format(value.getTime()).substring(5, 7))) - value.getSignTime());
            if (value.getMiss() == 0) value.setTot(value.getTot() + value.getEmployee().getSalary().getBonus());
            monthSalaryList.add(value);
        }

        redisUtil.set(key, monthSalaryList);
        redisUtil.expire(key, 60);  // 设置缓存一分钟之后过期
        return monthSalaryList;
    }
}
